home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / tex / dvi / dvipssrc.zoo / download.c < prev    next >
C/C++ Source or Header  |  1990-11-17  |  8KB  |  303 lines

  1. /*
  2.  *   Code to download a font definition at the beginning of a section.
  3.  */
  4. #include "structures.h" /* The copyright notice in that file is included too! */
  5. /*
  6.  *   These are the external routines we call.
  7.  */
  8. extern int free() ;
  9. extern void numout() ;
  10. extern void mhexout() ;
  11. extern void cmdout() ;
  12. extern long unpack() ;
  13. extern void flip() ;
  14. extern void specialout() ;
  15. extern long getlong() ;
  16. extern void error() ;
  17. extern char *nextstring ;
  18. /*
  19.  *   These are the external variables we access.
  20.  */
  21. extern FILE *bitfile ;
  22. extern fontdesctype *curfnt ;
  23. extern long bytesleft ;
  24. extern quarterword *raster ;
  25. extern Boolean compressed ;
  26. extern integer mag ;
  27. /*
  28.  *   We might use malloc here.
  29.  */
  30. extern char *malloc() ;
  31. static unsigned char dummyend[8] = { 252 } ;
  32. /*
  33.  *   We have a routine that downloads an individual character.
  34.  */
  35. static int lastccout ;
  36. void downchar(c, cc)
  37. chardesctype *c ;
  38. shalfword cc ;
  39. {
  40.    register long i, j ;
  41.    register halfword cheight, cwidth ;
  42.    register long k ;
  43.    register quarterword *p ;
  44.    register halfword cmd ;
  45.    register shalfword xoff, yoff ;
  46.    halfword wwidth = 0 ;
  47.    register long len ;
  48.    int smallchar ;
  49.  
  50.    p = c->packptr ;
  51.    cmd = *p++ ;
  52.    if (cmd & 4) {
  53.       if ((cmd & 7) == 7) {
  54.          cwidth = getlong(p) ;
  55.          cheight = getlong(p + 4) ;
  56.          xoff = getlong(p + 8) ;
  57.          yoff = getlong(p + 12) ;
  58.          p += 16 ;
  59.       } else {
  60.          cwidth = p[0] * 256 + p[1] ;
  61.          cheight = p[2] * 256 + p[3] ;
  62.          xoff = p[4] * 256 + p[5] ; /* N.B.: xoff, yoff are signed halfwords */
  63.          yoff = p[6] * 256 + p[7] ;
  64.          p += 8 ;
  65.       }
  66.    } else {
  67.       cwidth = *p++ ;
  68.       cheight = *p++ ;
  69.       xoff = *p++ ;
  70.       yoff = *p++ ;
  71.       if (xoff > 127)
  72.          xoff -= 256 ;
  73.       if (yoff > 127)
  74.          yoff -= 256 ;
  75.    }
  76.    if (c->flags & BIGCHAR)
  77.       smallchar = 0 ;
  78.    else
  79.       smallchar = 5 ;
  80.    if (compressed) {
  81.       len = getlong(p) ;
  82.       p += 4 ;
  83.    } else {
  84.       wwidth = (cwidth + 15) / 16 ;
  85.       i = 2 * cheight * (long)wwidth ;
  86.       if (i <= 0)
  87.          i = 2 ;
  88.       i += smallchar ;
  89.       if (bytesleft < i) {
  90.          if (bytesleft >= RASTERCHUNK)
  91.             (void) free((char *) raster) ;
  92.          if (RASTERCHUNK > i) {
  93.             raster = (quarterword *)malloc(RASTERCHUNK) ;
  94.             bytesleft = RASTERCHUNK ;
  95.          } else {
  96.             raster = (quarterword *)malloc((unsigned)i) ;
  97.             bytesleft = i ;
  98.          }
  99.          if (raster == NULL) {
  100.             error("! out of memory during allocation") ;
  101.          }
  102.       }
  103.       k = i;
  104.       while (k > 0)
  105.          raster[--k] = 0 ;
  106.       unpack(p, (halfword *)raster, cwidth, cheight, cmd) ;
  107.       p = raster ;
  108.       len = i - smallchar ;
  109.    }
  110.    if (cheight == 0 || cwidth == 0 || len == 0) {
  111.       cwidth = 1 ;
  112.       cheight = 1 ;
  113.       wwidth = 1 ;
  114.       len = 2 ;
  115.       if (compressed)
  116.          p = dummyend ;  /* CMD(END); see repack.c */
  117.       else
  118.          raster[0] = 0 ;
  119.    }
  120.    if (smallchar) {
  121.       p[len] = cwidth ;
  122.       p[len + 1] = cheight ;
  123.       p[len + 2] = xoff + 128 ;
  124.       p[len + 3] = yoff + 128 ;
  125.       p[len + 4] = c->pixelwidth ;
  126.    } else
  127. /*
  128.  *   Now we actually send out the data.
  129.  */
  130.       specialout('[') ;
  131.    if (compressed) {
  132.       specialout('<') ;
  133.       mhexout(p, len + smallchar) ;
  134.       specialout('>') ;
  135.    } else {
  136.       i = (cwidth + 7) / 8 ;
  137.       if (i * cheight > 65520) {
  138.          long bc = 0 ;
  139.          specialout('<') ;
  140.          for (j=0; j<cheight; j++) {
  141.             if (bc + i > 65520) {
  142.                specialout('>') ;
  143.                specialout('<') ;
  144.                bc = 0 ;
  145.             }
  146.             mhexout(p, i) ;
  147.             bc += i ;
  148.             p += 2*wwidth ;
  149.          }
  150.          specialout('>') ;
  151.       } else {
  152.          specialout('<') ;
  153.          if (2 * wwidth == i)
  154.             mhexout(p, ((long)cheight) * i + smallchar) ;
  155.          else {
  156.             for (j=0; j<cheight; j++) {
  157.                mhexout(p, i) ;
  158.                p += 2*wwidth ;
  159.             }
  160.             if (smallchar)
  161.                mhexout(p, (long)smallchar) ;
  162.          }
  163.          specialout('>') ;
  164.       }
  165.    }
  166.    if (smallchar == 0) {
  167.       numout((integer)cwidth) ;
  168.       numout((integer)cheight) ;
  169.       numout((integer)xoff + 128) ; /* not all these casts needed. */
  170.       numout((integer)yoff + 128) ;
  171.       numout((integer)(c->pixelwidth)) ;
  172.    }
  173.    if (lastccout + 1 == cc) {
  174.       cmdout("I") ;
  175.    } else {
  176.       numout((integer)cc) ;
  177.       cmdout("D") ;
  178.    }
  179.    lastccout = cc ;
  180. }
  181. /*
  182.  * Output the literal name of the font change command with PostScript index n
  183.  */
  184. void
  185. lfontout(n)
  186. int n ;
  187. {
  188.     char buf[10];
  189.     if (n < 27)
  190.         (void)sprintf(buf, "/f%c", 'a'+n-1) ;
  191.     else
  192.         (void)sprintf(buf, "/f%d", n-27) ;
  193.     cmdout(buf);
  194. }
  195. static char goodnames[] =
  196.    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ;
  197. void makepsname(s, n)
  198. register char *s ;
  199. register int n ;
  200. {
  201.    n-- ;
  202.    *s++ = 'F' + n / sizeof(goodnames) ;
  203.    *s++ = goodnames[n % sizeof(goodnames)] ;
  204.    *s++ = 0 ;
  205. }
  206. /*
  207.  *   And the download procedure.
  208.  */
  209. void download(p, psfont)
  210. charusetype *p ;
  211. int psfont ;
  212. {
  213.    register halfword b, bit ;
  214.    register chardesctype *c ;
  215.    int cc, maxcc = -1, numcc ;
  216.    char name[10] ;
  217.  
  218.    lastccout = -5 ;
  219.    name[0] = '/' ;
  220.    makepsname(name + 1, psfont) ;
  221.    curfnt = p->fd ;
  222.    curfnt->psname = psfont ;
  223.    if (curfnt->resfont) {
  224.       struct resfont *rf = curfnt->resfont ;
  225. /*
  226.  *   I'm not sure why we tried to download each font only
  227.  *   once here---we definitely need it each time . . .
  228.  */
  229. /*    if (rf->sent == 0) { */
  230.          cmdout(name) ;
  231.          cmdout("[") ;
  232.          c = curfnt->chardesc ;
  233.          for (cc=0; cc<256; cc++, c++)
  234.             numout((integer)c->pixelwidth) ;
  235.          cmdout("]") ;
  236.          (void)strcpy(nextstring, "/") ;
  237.          (void)strcat(nextstring, rf->PSname) ;
  238.          cmdout(nextstring) ;
  239.          if (rf->specialinstructions)
  240.                cmdout(rf->specialinstructions) ;
  241.          (void)sprintf(nextstring, "%ld", mag) ;
  242.          cmdout(nextstring) ;
  243.          (void)sprintf(nextstring, "%ld", curfnt->scaledsize) ;
  244.          cmdout(nextstring) ;
  245.          cmdout("rf") ;
  246.          rf->sent = 1 ;
  247. /*    } */
  248.       return ;
  249.    }
  250. /*
  251.  *   Here we calculate the largest character actually used, and
  252.  *   send it as a parameter to df.
  253.  */
  254.    cc = 0 ;
  255.    numcc = 0 ;
  256.    for (b=0; b<16; b++) {
  257.       for (bit=32768; bit!=0; bit>>=1) {
  258.          if (p->bitmap[b] & bit) {
  259.             maxcc = cc ;
  260.             numcc++ ;
  261.          }
  262.          cc++ ;
  263.       }
  264.    }
  265.    if (numcc <= 0)
  266.       return ;
  267.    cmdout(name) ;
  268.    numout((integer)numcc) ;
  269.    numout((integer)maxcc + 1) ;
  270. /*
  271.  *   If we need to scale the font, we say so by using dfs
  272.  *   instead of df, and we give it a scale factor.  We also
  273.  *   scale the character widths; this is ugly, but scaling
  274.  *   fonts is ugly, and this is the best we can probably do.
  275.  */
  276.    if (curfnt->dpi != curfnt->loadeddpi) {
  277.       numout((integer)curfnt->dpi) ;
  278.       numout((integer)curfnt->loadeddpi) ;
  279.       if (curfnt->alreadyscaled == 0) {
  280.          for (b=0, c=curfnt->chardesc; b<256; b++, c++)
  281.             c->pixelwidth = (c->pixelwidth * 
  282.       (long)curfnt->dpi * 2 + curfnt->loadeddpi) / (2 * curfnt->loadeddpi) ;
  283.          curfnt->alreadyscaled = 1 ;
  284.       }
  285.       cmdout("dfs") ;
  286.    } else
  287.       cmdout("df") ;
  288.    c = curfnt->chardesc ;
  289.    cc = 0 ;
  290.    for (b=0; b<16; b++) {
  291.       for (bit=32768; bit; bit>>=1) {
  292.          if (p->bitmap[b] & bit) {
  293.             downchar(c, cc) ;
  294.             c->flags |= EXISTS ;
  295.          } else
  296.             c->flags &= ~EXISTS ;
  297.          c++ ;
  298.          cc++ ;
  299.       }
  300.    }
  301.    cmdout("E") ;
  302. }
  303.